package com.liu.nb.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.liu.nb.entity.SysMenu;
import com.liu.nb.entity.SysRole;
import com.liu.nb.entity.SysUser;
import com.liu.nb.mapper.SysUserMapper;
import com.liu.nb.service.ISysUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liu.nb.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author liuziyi
 * @since 2021-08-05
 */
@Service
public class SysUserService extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {
    @Autowired
    SysRoleService sysRoleService;
    @Autowired
    SysUserMapper sysUserMapper;
    @Autowired
    SysMenuService sysMenuService;
    @Autowired
    RedisUtil redisUtil;
    @Override
    public SysUser getByUsername(String username) {
        return getOne(new QueryWrapper<SysUser>().eq("username",username));
    }

    /*
    * 获取权限信息
    * */
    @Override
    public String getUserAuthorityInfo(long userId) {
        SysUser sysUser = sysUserMapper.selectById(userId);
//        记录用户角色和用户权限的字符串
        String authority="";
//        每次先判断一下缓存内有没有权限
        if (redisUtil.hasKey("UserAuthority:"+sysUser.getUsername())){
//            如果有直接取出来返回
            return (String)redisUtil.get("UserAuthority:" + sysUser.getUsername());
        }
        //获取角色
        List<SysRole> roles = sysRoleService.list(new QueryWrapper<SysRole>()
                .inSql("id", "select role_id from sys_user_role where user_id=" + userId));
        if (roles.size()>0){
//          这行代码的能把list集合转换成字符串并且用“ , ”隔开
            String roleCodes = roles.stream().map(r ->"ROLE_"+r.getCode()).collect(Collectors.joining(","));
            authority  = roleCodes.concat(",");
        }
        //获取菜单操作编码（用户的权限）
        List<Long> menuIds = sysUserMapper.getNavMenuIds(userId);//获取用户的权限id
        if (menuIds.size() > 0){
            List<SysMenu> menus = sysMenuService.listByIds(menuIds);//根据用户的权限id，获取该权限的的名称
            //          这行代码的能把list集合转换成字符串并且用“ , ”隔开
            String collect = menus.stream().map(m -> m.getPerms()).collect(Collectors.joining(","));
            authority=authority.concat(collect);
        }
//        把用户权限放到缓存里面，减少对数据库的访问
        redisUtil.set("UserAuthority:"+sysUser.getUsername(),authority,60*60);
        return authority;
    }

//    根据用户名删除缓存
    @Override
    public void clearAuthorityInfoByUserName(String username) {
        redisUtil.del("UserAuthority:"+username);
    }
//  根据角色信息删除缓存
    @Override
    public void clearAuthorityInfoByRoleId(Long roleId) {
        List<SysUser> sysUsers = this.list(new QueryWrapper<SysUser>().inSql("id", "select user_id from sys_user_role where role_id = " + roleId));
        sysUsers.forEach(u ->{
            this.clearAuthorityInfoByUserName(u.getUsername());
        });
    }
//  根据菜单信息删除缓存
    @Override
    public void clearAuthorityInfoByMenuId(Long menuId) {
        List<SysUser> sysUsers = sysUserMapper.listByMenuId(menuId);
        sysUsers.forEach(u ->{
            this.clearAuthorityInfoByUserName(u.getUsername());
        });
    }

}
